package pl.edu.agh.iosr.gamblingzone.model;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.AttributeOverride;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

/**
 * The Class BettingSlip.
 *
 * 
 * @author maciej
 */
@AttributeOverride(name = "id", column = @Column(name = "BETTING_SLIP_ID"))
@Entity(name = "BETTING_SLIPS")
@Inheritance(strategy = InheritanceType.JOINED)
public class BettingSlip extends EntityModel {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = -7277625657154685200L;

	/** The money. */
	@Column(name = "BETTING_SLIP_MONEY", nullable = false)
	private Long money = 0L;

	/** The was paid. */
	@Column(name = "BETTING_SLIP_WAS_PAID", nullable = false)
	private boolean wasPaid = false;

	@Column(name = "BETTING_SLIP_CREATE_DATE", nullable = false)
	private Date creationDate = new Date();

	/** The owner. */
	@ManyToOne
	@JoinTable(name = "USER_BETTINGSLIP", joinColumns = { @JoinColumn(name = "BETTING_SLIP_ID") }, inverseJoinColumns = { @JoinColumn(name = "USER_ID") })
	private User owner;

	/** The bets. */
	@OneToMany(mappedBy="bettingSlip", cascade=CascadeType.ALL)
	private Set<Bet> bets = new HashSet<Bet>();

	/**
	 * Gets the money.
	 * 
	 * @return the money
	 */
	public Long getMoney() {
		return money;
	}

	/**
	 * Sets the money.
	 * 
	 * @param money
	 *            the new money
	 */
	public void setMoney(Long money) {
		this.money = money;
	}

	/**
	 * Checks if is was paid.
	 * 
	 * @return true, if is was paid
	 */
	public boolean isWasPaid() {
		return wasPaid;
	}

	/**
	 * Sets the was paid.
	 * 
	 * @param wasPaid
	 *            the new was paid
	 */
	public void setWasPaid(boolean wasPaid) {
		this.wasPaid = wasPaid;
	}

	/**
	 * Gets the owner.
	 * 
	 * @return the owner
	 */
	public User getOwner() {
		return owner;
	}

	/**
	 * Sets the owner.
	 * 
	 * @param owner
	 *            the new owner
	 */
	protected void setOwner(User owner) {
		this.owner = owner;
	}

	/**
	 * Adds the bet.
	 * 
	 * Creates bidirectional association & automatically make Bet persistent.
	 * 
	 * @param b
	 *            the b
	 */
	public void addBet(Bet b) {
		b.setBettingSlip(this);
		this.bets.add(b);
	}
	
	/**
	 * Removes the bet.
	 * 
	 * @param b the b
	 */
	public void removeBet(Bet b) {
		b.setBettingSlip(null);
		this.bets.remove(b);
	}


	/**
	 * Gets the bets.
	 * 
	 * @return the bets
	 */
	public Set<Bet> getBets() {
		return bets;
	}

	/**
	 * Gets the creation date.
	 * 
	 * @return the creation date
	 */
	public Date getCreationDate() {
		return creationDate;
	}

	/**
	 * Sets the creation date.
	 * 
	 * @param creationDate
	 *            the new creation date
	 */
	public void setCreationDate(Date creationDate) {
		this.creationDate = creationDate;
	}
	
	/* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
	// TODO
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof BettingSlip)) return false;

        final BettingSlip bettingSlip = (BettingSlip) o;
        
        if ((getId() == null || getId() == 0L) || (bettingSlip.getId() == null || bettingSlip.getId() == 0L)) {
        	 if (!creationDate.equals(bettingSlip.creationDate)) return false;
        } else {
        	 if (!getId().equals(bettingSlip.getId()) ) return false;
        }
     
        return true;
    }
    
    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    // TODO
    public int hashCode() {
    	int result = 17;

    	if (getId() == null || getId() == 0L) {
    		result = 37 * result + getCreationDate().hashCode();
    	} else {
    		result = getId().hashCode();
    	}
    	
    	return result;
    }
	
}
